using System;
using System.Collections.Generic;
using System.Text;
using Toenda.Foundation;

using Toenda.Foundation.Utility;

namespace Toenda.Foundation.Mathematics {
	/// <summary>
	/// Class MathQueryParser
	/// </summary>
	public class MathQueryParser {
		private char[] _mathSymbols;
		private string _stringToParse;

		// ---------------------------------------------------
		// CONSTRUCTORS
		// ---------------------------------------------------

		/// <summary>
		/// Default Ctor
		/// </summary>
		public MathQueryParser() {
			char[] mathSymbols = { '+', '-', '*', '/', '%', '(', ')' };
			this._mathSymbols = mathSymbols;
		}

		/// <summary>
		/// Specific Ctor
		/// </summary>
		/// <param name="mathQueryToParse">The MathQuery script string.</param>
		public MathQueryParser(string mathQueryToParse) {
			char[] mathSymbols = { '+', '-', '*', '/', '%', '(', ')' };

			this._mathSymbols = mathSymbols;
			this._stringToParse = mathQueryToParse;
		}

		/// <summary>
		/// Specific Ctor
		/// </summary>
		/// <param name="mathQueryToParse">The MathQuery script string.</param>
		/// <param name="mathSymbols">A char array of mathematic symbols to parse.</param>
		public MathQueryParser(string mathQueryToParse, char[] mathSymbols) {
			List<char> symbols = new List<char>();
			char[] ms = { '+', '-', '*', '/', '%', '(', ')' };

			symbols.AddRange(ms);
			symbols.AddRange(mathSymbols);

			this._mathSymbols = symbols.ToArray();
			this._stringToParse = mathQueryToParse;
		}

		// ---------------------------------------------------
		// INTERFACE IMPLEMENTATIONS
		// ---------------------------------------------------

		// ---------------------------------------------------
		// PROPERTIES
		// ---------------------------------------------------

		/// <summary>
		/// Get or set the MathQuery string to parse
		/// </summary>
		public string MathQueryToParse {
			get { return this._stringToParse; }
			set { this._stringToParse = value; }
		}

		/// <summary>
		/// Get or set the char array of the mathematic symbols.
		/// </summary>
		public char[] MathSymbols {
			get { return this._mathSymbols; }
			set { this._mathSymbols = value; }
		}

		// ---------------------------------------------------
		// EVENTS
		// ---------------------------------------------------

		// ---------------------------------------------------
		// PRIVATE MEMBERS
		// ---------------------------------------------------

		// ---------------------------------------------------
		// PROTECTED MEMBERS
		// ---------------------------------------------------

		// ---------------------------------------------------
		// PUBLIC MEMBERS
		// ---------------------------------------------------

		/// <summary>
		/// Parse a MathQuery string
		/// </summary>
		/// <returns>A array of all symbols and fragment strings.</returns>
		public string[] Parse() {
			return this.Parse(this._stringToParse);
		}

		/// <summary>
		/// Parse a MathQuery string
		/// </summary>
		/// <param name="mathQueryToParse">The MathQuery script string.</param>
		/// <returns>A array of all symbols and fragment strings.</returns>
		public string[] Parse(string mathQueryToParse) {
			return this.Parse(mathQueryToParse, this._mathSymbols);
		}

		/// <summary>
		/// Parse a MathQuery string
		/// </summary>
		/// <param name="mathQueryToParse">The MathQuery script string.</param>
		/// <param name="mathSymbols">A char array of mathematic symbols to parse.</param>
		/// <returns>A array of all symbols and fragment strings.</returns>
		public string[] Parse(string mathQueryToParse, char[] mathSymbols) {
			char[] symbols = mathSymbols;
			string query = mathQueryToParse + "|";

			int count = 0;
			string tmp = "";
			List<string> list = new List<string>();

			foreach(char sym in query) {
				if(sym != ' ') {
					if(Validator.IsInList(symbols, sym)) {
						if(tmp.Trim() != "") {
							//Console.WriteLine("      number1: " + tmp);
							list.Add(tmp);
						}

						tmp = "";

						tmp += sym.ToString();

						//Console.WriteLine("   symbol: " + tmp);

						list.Add(tmp);
						tmp = "";
					}
					else {
						tmp += sym.ToString();

						if(sym == '|') {
							tmp = tmp.Substring(0, tmp.Length - 1);

							list.Add(tmp);

							//Console.WriteLine("      number2: " + tmp);
						}

						//tmp = "";
					}

					count++;
				}
			}

			return list.ToArray();
		}
	}
}
